#!/usr/bin/env python
# coding=utf-8

import os
import time
import urllib
import wsgiref.handlers
import hashlib

from google.appengine.api.labs import taskqueue
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.api import urlfetch
from google.appengine.api import memcache
from google.appengine.ext import db
from google.appengine.api import users


from auth import SECRET,ROOTSITE
from lock import CcdjhMarxHandler
from suki.cloud import Datum, Article, Category, Comment
from suki.cloud.purview import CheckAuth, DoAuth, CheckAuthSilence, DoAuthSilence

from suki.cloud.bot.sessions import Session
from suki.cloud.bot.cookies import Cookies

from django.core.paginator import ObjectPaginator, InvalidPage
from django.utils import simplejson

class IndoorDashboardHandler(CcdjhMarxHandler):
	def get(self):
		self.session = Session()
		self.lockKey('/indoor/dashboard')
		message = self.lockmessage(self.request.get('message'))
		site_author = Datum.get('site_author')
		site_domain = Datum.get('site_domain')
		site_name = Datum.get('site_name')
		articles = db.GqlQuery("SELECT * FROM Article ORDER BY created DESC")
		PAGE_SIZE = 10
		paginator = ObjectPaginator(articles, PAGE_SIZE)
		try:
			page = int(self.request.get('page', 0))
			articles = paginator.get_page(page)
		except InvalidPage:
			articles = paginator.get_page(int(paginator.pages - 1))
		if paginator.pages > 1:
			is_paginated = True
		else:
			is_paginated = False
		if site_domain[0] is None or site_name[0] is None or site_author[0] is None:
			site_configured = False
		else:
			site_configured = True
		if is_paginated:
			self.session['page'] = page
		#template_values = {}
		template_values = {
			'site_configured' : site_configured,
			'is_paginated' : is_paginated,
			'page_size' : PAGE_SIZE,
			'page_has_next' : paginator.has_next_page(page),
			'page_has_previous' : paginator.has_previous_page(page),
			'page' : page,
			'next' : page + 1,
			'previous' : page - 1,
			'pages' : paginator.pages,
			'articles' : articles,
			'articles_total' : len(articles),
			'page_range' : range(0, paginator.pages),
			#'urls' : urls
		}
		template_values['message'] = message
		
		path = os.path.join(os.path.dirname(__file__), 'tpl', 'indoor', 'default', 'dashboard.html')
		self.response.out.write(template.render(path, template_values))

class IndoorSettingsHandler(CcdjhMarxHandler):
	def get(self):
		self.lockKey('/indoor/settings')
		themes = os.listdir(os.path.join(os.path.dirname(__file__), 'tpl', 'outdoor'))
		site_title = Datum.get('site_title')
		site_slogan = Datum.get('site_slogan')
		site_author = Datum.get('site_author')
		site_email = Datum.get('site_email')
		site_domain = Datum.get('site_domain')
		site_theme = Datum.get('site_theme')
		template_values = {}
		template_values['site_title'] = site_title[0]
		template_values['site_slogan'] = site_slogan[0]
		template_values['site_author'] = site_author[0]
		template_values['site_email'] = site_email[0]
		template_values['site_domain'] = site_domain[0]
		template_values['site_theme'] = site_theme[0]
		template_values['themes'] = themes
		path = os.path.join(os.path.dirname(__file__), 'tpl', 'indoor', 'default', 'setting.html')
		self.response.out.write(template.render(path, template_values))

	def post(self):
		self.lockKey('/indoor/settings')
		Datum.set('site_title', self.request.get('site_title'))
		Datum.set('site_slogan', self.request.get('site_slogan'))
		Datum.set('site_author', self.request.get('site_author'))
		Datum.set('site_email', self.request.get('site_email'))
		Datum.set('site_domain', self.request.get('site_domain'))
		themes = os.listdir(os.path.join(os.path.dirname(__file__), 'tpl', 'outdoor'))
		if self.request.get('site_theme') in themes:
			Datum.set('site_theme', self.request.get('site_theme'))
		else:
			Datum.set('site_theme', 'default')
		self.redirect('/indoor/settings')


class IndoorNewHandler(CcdjhMarxHandler):
	def get(self):
		self.lockKey('/indoor')
		is_page = self.request.get('is-page')
		article_url_time = time.strftime("%Y-%m-%d-%H-%M-%SZ", time.gmtime())
		category = db.GqlQuery("SELECT * FROM Category ORDER BY name ASC")
		template_values = {}
		template_values['article_url_time'] = article_url_time
		template_values['is_page'] = is_page
		template_values['category'] = category
		path = os.path.join(os.path.dirname(__file__), 'tpl', 'indoor', 'default', 'article.html')
		self.response.out.write(template.render(path, template_values))


class IndoorSaveHandler(CcdjhMarxHandler):
	def get(self):
		self.redirect('/indoor')


	def post(self):
		self.lockKey('/indoor')
		article = Article()
		article.title = self.request.get('article_title')
		article.content = self.request.get('article_content')
		article.title_url = self.request.get('title_url')
		article.title_link = self.request.get('title_link')
		
		article_category_url = self.request.get_all('article_category_url')#self.request.get_all from GAE Request class
		for article_cate in article_category_url:
			article.article_list.append(article_cate)
		
		if (self.request.get('article_have_comment') == 'True'):
			article.have_comment = True
		else:
			article.have_comment = False 
		
		if (self.request.get('is-page') == 'True'):
			article.is_page = True
		else:
			article.is_page = False 
		if (self.request.get('article_attribute_for_sidebar') == 'True'):
			article.is_for_sidebar = True
		else:
			article.is_for_sidebar = False 
		article.put()
		Datum.set('site_updated', time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()))
		site_domain,ccdjh = Datum.get('site_domain')
		site_name,ccdjh = Datum.get('site_title')
		if site_domain.find('localhost') == -1: #Bug site_domain
			try:
				google_ping = 'http://blogsearch.google.com/ping?name=' + urllib.quote(site_name) + '&url=http://' + urllib.quote(site_domain) + '/&changesURL=http://' + urllib.quote(site_domain) + '/sitemap.xml'
				result = urlfetch.fetch(google_ping)
			except:
				taskqueue.add(url='/indoor/ping-article')
		obsolete = ['feed_output', 'index', 'index_output']
		memcache.delete_multi(obsolete)
		self.redirect('/indoor?message=creatd-article')

class IndoorEditHandler(CcdjhMarxHandler):
	def get(self, key = ''):
		self.lockKey('/indoor')
		if (key):
			article = db.get(db.Key(key))
		template_values = {}
		template_values['article'] = article
		path = os.path.join(os.path.dirname(__file__), 'tpl', 'indoor', 'default', 'article.html')
		self.response.out.write(template.render(path, template_values))

	def post(self, key = ''):
		self.lockKey('/indoor')
		if (key):
			article = db.get(db.Key(key))
			article.title = self.request.get('article_title')
			article.content = self.request.get('article_content')
			article.title_url = self.request.get('title_url')
			article.title_link = self.request.get('title_link')
			article.put()
		self.redirect('/indoor')

class IndoorPingHandler(webapp.RequestHandler):
	def get(self):
		site_domain,ccdjh = Datum.get('site_domain')
		site_name,ccdjh = Datum.get('site_title')
		try:
			google_ping = 'http://blogsearch.google.com/ping?name=' + urllib.quote(site_name) + '&url=http://' + urllib.quote(site_domain) + '/&changesURL=http://' + urllib.quote(site_domain) + '/index.xml'
			result = urlfetch.fetch(google_ping)
			if result.status_code == 200:
				self.response.out.write('OK: Google Blog Search Ping: ' + google_ping)
			else:
				self.response.out.write('Reached but failed: Google Blog Search Ping: ' + google_ping)
		except:
			self.response.out.write('Failed: Google Blog Search Ping: ' + google_ping)

class IndoorRemoveHandler(CcdjhMarxHandler):
	def get(self, key = ''):
		self.lockKey('/indoor')
		if (key):
			article = db.get(db.Key(key))
			article.delete()
		self.redirect('/indoor/dashboard')

class IndoorRemoveCategoryHandler(CcdjhMarxHandler):
	def get(self, url = ''):
		self.lockKey('/indoor')
		if (url):
			category = db.GqlQuery("SELECT * FROM Category WHERE category_url = :1", url)
			category = category[0]
			category.delete()
			articles = Article.gql("WHERE article_list = :1 ORDER BY created DESC", url)
			for article in articles:
				article.article_list.remove(url)
				article.put()
		self.redirect('/indoor/dashboard')

class IndoorEditCategoryHandler(CcdjhMarxHandler):
	def get(self, url = ''):
		self.lockKey('/indoor')
		if (url):
			category = db.GqlQuery("SELECT * FROM Category WHERE category_url = :1", url)
			category = category[0]
		template_values = {}
		template_values['category'] = category
		path = os.path.join(os.path.dirname(__file__), 'tpl', 'indoor', 'default', 'category-edit.html')
		self.response.out.write(template.render(path, template_values))

	def post(self, url = ''):
		self.lockKey('/indoor')
		if (url):
			category = db.GqlQuery("SELECT * FROM Category WHERE category_url = :1", url)
			category = category[0]
			category.name = self.request.get('article_category')
			new_url = self.request.get('article_category_url')
			if new_url != url:
				category.category_url = self.request.get('article_category_url')
				articles = Article.gql("WHERE article_list = :1 ORDER BY created DESC", url)
				for article in articles:
					article.article_list.remove(url)
					article.article_list.append(new_url)
					article.put()
			category.put()
		self.redirect('/indoor/category-article')



class IndoorQuickFindHandler(webapp.RequestHandler):
	def get(self):
		pass

class IndoorCategoryHandler(CcdjhMarxHandler):
	def get(self):
		self.lockKey('/indoor')
		category = db.GqlQuery("SELECT * FROM Category ORDER BY name ASC")
		article_url_time = time.strftime("%Y-%m-%d-%H-%M-%SZ", time.gmtime())
		template_values = {}
		template_values['category'] = category
		template_values['article_url_time'] = article_url_time
		path = os.path.join(os.path.dirname(__file__), 'tpl', 'indoor', 'default', 'category.html')
		self.response.out.write(template.render(path, template_values))

	def post(self):
		self.lockKey('/indoor')
		category = Category()
		category.name = self.request.get('article_category')
		category.category_url = self.request.get('article_category_url')
		category.put()
		self.redirect('/indoor/category-article')

class IndoorAdminHandler(CcdjhMarxHandler):
	def get(self):
		self.lockKey('/indoor')
		template_values = {}
		template_values['category'] = 'category'
		path = os.path.join(os.path.dirname(__file__), 'tpl', 'indoor', 'default', 'admin.html')
		self.response.out.write(template.render(path, template_values))

	def post(self):
		self.lockKey('/indoor')
		old_password = self.request.get('old_password')
		new_password = self.request.get('new_password')
		confirm_password = self.request.get('confirm_password')
		a = db.GqlQuery("SELECT * FROM Admin")
		if new_password != confirm_password:
			self.redirect('/indoor/admin?message=confirm-wrong')
		if a.count() == 1:
			if hashlib.sha1(old_password).hexdigest() == a[0].author_password:
				a = a[0]
				a.author_password = hashlib.sha1(new_password).hexdigest()
				a.put()
				cookies = Cookies(self, max_age = 86400, path = '/')
				if 'auth' in cookies:
					del cookies['auth']
				b = db.GqlQuery("SELECT * FROM Admin")
				cookies['auth'] = hashlib.sha1(b[0].author_password + ':' + b[0].author_name).hexdigest()
				self.redirect('/indoor/admin?message=new-password-ok')
			else:
				self.redirect('/indoor/admin?message=old-password-wrong')

class IndoorCommentHandler(CcdjhMarxHandler):
	def get(self):
		self.redirect('/indoor')


	def post(self):
		self.lockKey('/indoor')
		article_comment_content = self.request.get('article_comment_content')
		article_comment_author_name = self.request.get('article_comment_author_name')
		article_comment_parent_url = self.request.get('article_comment_parent_url')
		article_comment_message_email = self.request.get('article_comment_message_email')
		article_comment_message_name = self.request.get('article_comment_message_name')
		cookies = Cookies(self, max_age = 86400, path = '/')
		if 'commentlogin' in cookies:
			comment = Comment()
			comment.comment_content = str(article_comment_content)
			comment.comment_parent_url = article_comment_parent_url
			comment.author_email = article_comment_message_email
			if (self.request.get('article_comment_author_name')==''):
				comment.author_name = article_comment_message_name
			else:
				comment.author_name = article_comment_author_name
			comment.put()
			self.redirect('/' + article_comment_parent_url)
		else:
			self.redirect('/')

class IndoorCommentLoginHandler(CcdjhMarxHandler):
	def get(self):
		url = self.request.get('p')
		user = users.get_current_user()
		try:
			user_nickname = user.nickname()
			user_email = user.email()
			cookies = Cookies(self, max_age = 86400, path = '/')
			cookies['commentlogin'] = hashlib.sha1(user_email + ':' + 'ccdjh').hexdigest()
			self.session = Session()
			self.session['commentmessage'] = user_nickname
			self.session['commentmessage_email'] = user_email
			self.redirect('/' + url)
		except:
			#greeting = ("<a href=\"%s\">Sign in or register</a>." %users.create_login_url("/intl/zh-CN/"))
			self.redirect(users.create_login_url('/' + url))

class IndoorCommentLogoutHandler(CcdjhMarxHandler):
	def get(self):
		url = self.request.get('p')
		cookies = Cookies(self, max_age = 86400, path = '/')
		if 'commentlogin' in cookies:
			del cookies['commentlogin']
		self.session = Session()
		self.session['commentmessage'] = 'Guest'
		self.session['commentmessage_email'] = 'robot'
		self.redirect('/' + url)


def main():
	application = webapp.WSGIApplication([
	('/indoor', IndoorDashboardHandler),
	('/indoor/dashboard', IndoorDashboardHandler),
	('/indoor/comment', IndoorCommentHandler),
	('/indoor/comment/login', IndoorCommentLoginHandler),#use to text google
	('/indoor/comment/logout', IndoorCommentLogoutHandler),#use to text google
	('/indoor/admin', IndoorAdminHandler),
	('/indoor/settings', IndoorSettingsHandler),
	('/indoor/category-article', IndoorCategoryHandler),
	('/indoor/remove-category-article/([0-9a-zA-Z\-\.]+)', IndoorRemoveCategoryHandler),
	('/indoor/edit-category-article/([0-9a-zA-Z\-\.]+)', IndoorEditCategoryHandler),
	('/indoor/new-article', IndoorNewHandler),
	('/indoor/save-article', IndoorSaveHandler),
	('/indoor/ping-article', IndoorPingHandler),
	#('/indoor/update-article/([0-9a-zA-Z\-]+)', IndoorSaveHandler),
	('/indoor/edit-article/([0-9a-zA-Z\-]+)', IndoorEditHandler),
	('/indoor/remove-article/([0-9a-zA-Z\-]+)', IndoorRemoveHandler),
	('/indoor/quick/find', IndoorQuickFindHandler)
	],
										debug=True)
	wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
  main()
